#pragma once

#include <SkinDefine.h>

#ifdef     _DEBUG

//////////////////////////////////////////////////////////////////////////


void ExportXSkinLib AddMemLog(void* ptr, LPCSTR szFilePath, int nLine, LPCSTR szTypeName, int nSize, int nCount);
void ExportXSkinLib DelMemLog(void* ptr);

// Without Data
template <typename T>
T* AllocHelper(LPCSTR szFilePath, int nLine, int nSize, int nCount)
{
    T* pResult = new T;
    AddMemLog(pResult, szFilePath, nLine, typeid(T).name(), nSize, nCount);
    return pResult;
};

// With One Data
template <typename T, typename D1>
T* AllocHelper(const D1& data1, LPCSTR szFilePath, int nLine, int nSize, int nCount)
{
    T* pResult = new T(data1);
    AddMemLog(pResult, szFilePath, nLine, typeid(T).name(), nSize, nCount);
    return pResult;
};

// With Two Data
template <typename T, typename D1, typename D2>
T* AllocHelper(const D1& data1, const D2& data2, LPCSTR szFilePath, int nLine, int nSize, int nCount)
{
    T* pResult = new T(data1, data2);
    AddMemLog(pResult, szFilePath, nLine, typeid(T).name(), nSize, nCount);
    return pResult;
};

template <typename T>
T* AllocArrayHelper(LPCSTR szFilePath, int nLine, int nSize, int nCount)
{
    T* pResult = new T[nCount];
    AddMemLog(pResult, szFilePath, nLine, typeid(T).name(), nSize, nCount);
    return pResult;
};

    #define XAlloc(type)                AllocHelper<type>(__FILE__, __LINE__, sizeof(type), 1)
    #define XAllocD(type, ...)          AllocHelper<type>(__VA_ARGS__, __FILE__, __LINE__, sizeof(type), 1)
    #define XFree(ptr)                  do {    delete (ptr);   DelMemLog((ptr));   } while(false)

    #define XAllocArray(type, count)    AllocArrayHelper<type>(__FILE__, __LINE__, sizeof(type), count)
    #define XFreeArray(ptr)             do {    delete[](ptr);  DelMemLog((ptr));   } while(false)

#else   // _DEBUG

    #define XAlloc(type, ...)           new type(__VA_ARGS__)
    #define XAllocD(type, ...)          new type(__VA_ARGS__)
    #define XFree(ptr)                  delete (ptr);

    #define XAllocArray(type, count)    new type[count]
    #define XFreeArray(ptr)             delete[](ptr)

#endif  // _DEBUG
